/**
 * vue2.0响应式是借助Object.definedPrototyes实现的。
 * Object.difineddPrototypes方法
 * 1.configurable:表示能否通过delete删除属性，从而重新定义属性，能否修改属性的特征，或者能否把属性修改为访问器属性，默认值为false
 * 2.enumerable:表示能否通过for in循环访问属性，默认值为false
 * 3.witeable表示能否修改属性的值。默认值为false.
 * 4.value:包含这个属性的数据值。默认值为undefined
 */


var person = {
  _name: 'ikun',
  _age: 18,
  _hobby: '打篮球',
  _sex: 'nan'
}

//新增属性：sex,注意：不能同时指定访问器和值或可写属性
//这样写会报栈溢出，造成循环引用，狂call不止。
//流程：pserson.sex->get.call(person)->this.sex->person.sex->get.call(pserson)->this.sex...
//我们将属性的值进行改变后，可以发下只是在属性值前面加了一个下滑线，但这样就可以必须循环调用的问题。
//流程：person.sex -> get.call(person) -> this._sex = nv
Object.defineProperty(person, '_sex', {
  get: function () {
    console.log('sex的get方法');
    return this._sex;
  },
  set: function (newSex) {
    console.log('sex的set方法');
    if (newSex == 'nan' || newSex == 'nv') {
      this._sex = newSex;
    }
  }
})

// 给单个属性age添加拦截!!defineProperty!!
Object.defineProperty(person, "_age", {
  get: function () {
    console.log('调用了age.get方法');
    return this._age;
  },
  set: function (value) {
    if (value > 150) {
      console.log('超出限制');
      return
    } else {
      this._age = value;
      console.log('调用了age.set方法');
    }
  }
})


// 给多个属性添加拦截
// 现在，我们给hobby和name属性添加拦截!!defineProperties!!
Object.defineProperties(person, {
  name: {
    get() {
      return this._name;
    },
    set(v) {
      if (v.length > 20) {
        console.log('名字太长了，写短点');
        return
      } else {
        //以a-z,0-9,_-开头的，长度在10到18之间的
        let regstr = `(^[a-z0-9_-]{3,18}$)`;
        let reg = new RegExp(regstr);
        if (reg.test(v)) {
          this._name = v;
          return
        } else {
          console.log('正则匹配失败');
          return
        }
      }
    }
  },
  hobby: {
    get() {
      return this._hobby;
    },
    set(v) {
      this._hobby = v;
    }
  }
})



console.log(person)